/*
 License
 
 Copyright © 2012 Kevin Kimmich
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights to 
 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 the Software, and to permit persons to whom the Software is furnished to do so, 
 subject to the following conditions:
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

/**
 @file
 The wwwserver messaging layer provides an interface between sockets and requests.
 */

#ifndef _kuato_messaging_h
#define _kuato_messaging_h

#ifdef __cplusplus
extern "C" {
#endif	
	
#include "kuato_types.h"
		
	/**
	 Initialize the SSL layer.
	 */
#ifdef ENABLE_SSL
	int messaging_ssl_init(void);
#endif
	/**
	 Create a server socket SSL context, returns NULL on failure. Returns an SSL_CTX object on success.
	 @param cert_file The certification file name.
	 @param key_file The key file name.
	 */
	#ifdef ENABLE_SSL
	SSL_CTX* messaging_create_server_ssl_context(const char* cert_file, const char* key_file);
#endif
	/**
	 Create a context for making requests. Returns NULL on failure, a connection_context on success.
	 @param addr The address to connect to. See the address_init() function in utils.h for a helper.
	 */
	connection_context* create_client_context(struct sockaddr_in addr);
	
	/**
	 Creates a listener context. Returns NULL on failure, a connection context object on success.
	 @param addr The address to bind to.
	 @param max_conn The maximum number of connections.
	 @param h The http server object.
	 */
	connection_context* create_listener_context(struct sockaddr_in addr, int max_conn,http_server_object* h);
	
	/**
	 Creates a server context. A server context is created for every new TCP client connection. Returns NULL on failure
	 or a context object on success.
	 @param addr The address of the client.
	 @param fd The file descriptor of the socket.
	 */
	connection_context* create_server_context(struct sockaddr_in addr, int fd);
	
	/**
	 Same as create_server_context, but with SSL.
	 */
	#ifdef ENABLE_SSL
	connection_context* create_ssl_server_context(SSL_CTX* sslctx,struct sockaddr_in addr, int fd);

	/**
	 Same as create_client_context, but with SSL.
	 */
	connection_context* create_ssl_client_context(struct sockaddr_in addr);
	
	/**
	 Same as create_listener_context, but with SSL.
	 */
	connection_context* create_ssl_listener_context(struct sockaddr_in addr, int max_conn,http_server_object* h);
#endif	
	/**
	 Destroy a context.
	 @param ctx The context object.
	 */
	void destroy_context(connection_context* ctx);
	
	//Internals
	/**
	 Write to a socket and wait for it to finish
	 @param ctx The context object
	 @param timeout_msec The timeout in milliseconds or FOREVER
	 @param result The result of the operation.
	 @param bytes_sent The number of bytes sent during the operation.
	 */
	void context_wait_write(connection_context* ctx, int timeout_msec, io_result* result, int* bytes_sent);
	
	/**
	 read bytes from a context.
	 @param ctx The context object.
	 @param result The result of the operation.
	 @param bytes_received The number of bytes received during the operation.
	 */
	void context_read(connection_context* ctx, io_result* result, int* bytes_received);
	
#ifdef __cplusplus
}
#endif	


#endif //_messaging_h
